package com.iwhalecloud.bss.kite.cucc.service.attr.handler;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.enums.TriggerStrategy;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.ServiceOfferConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.inst.*;
import com.iwhalecloud.bss.kite.service.attr.AttrData;
import com.iwhalecloud.bss.kite.service.attr.handler.AbstractAttrHandler;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.ztesoft.bss.common.exception.BssException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 *
 */
public class ApnSelectAttrHandler extends AbstractAttrHandler<KiteInst, AttrData> {

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    IOperateSceneInstService operateSceneInstService;

    @Autowired
    OperateInstAttrService operateInstAttrService;

    @Override
    public void before(KiteAttr attr, KiteInst inst, String value, AttrData data) {
        //模版还原时，不做校验
        String extParam = querySceneInstService.getExtParameterValue(data.getSceneInstId(), "entry");
        if ("sceneTempl".equals(data.getExtAttributes().get("entry")) || "sceneTempl".equals(extParam)) {
            return;
        }
        //变更业务的场景初始化过程中不校验
        if (!ServiceOfferConsts.SERVICE_OFFER_ORDER.equals(data.getServiceOfferId())
            && !KeyConsts.IFTRUE_T.equals(querySceneInstService.getExtParameterValue(data.getSceneInstId(), LocalKeyConsts.BUSI_CHANGE_SCENE))) {
            return;
        }

        if (KiteStringUtils.isEmpty(value)) {
            return;
        }

        // 判断只有APN设置(资费计划) 才需要判断
        if (inst instanceof KiteProdInstFunc) {
            KiteProdInstFunc funcInst = (KiteProdInstFunc) inst;
            String[] to = value.split(",");
            // 首先获取接入实例，找到下面已经存在的资费
            List<KiteProdInstFunc> fees = getFeeFunc(data, funcInst);
            if (KiteListUtils.isEmpty(fees)) {
                return;
            }
            // 找到资费下面已经选择的apn，然后值在里面的就不允许
            for (KiteProdInstFunc fee : fees) {
                if (fee.getProdInstId().equals(funcInst.getProdInstId())) {
                    continue;
                }
                KiteAttr apnAttr = fee.getAttr(attr.getFieldName());
                if (apnAttr == null || KiteStringUtils.isEmpty(apnAttr.getValue())) {
                    continue;
                }
                String str = apnAttr.getValue();
                List<String> has = Arrays.asList(str.split(","));
                for (String v : to) {
                    if (has.contains(v)) {
                        BssException.throwOut("", "",  "已经选择了，不允许再选择");
                    }
                }
            }

        }


    }

    @Override
    public void onShow(KiteAttr attr, KiteInst inst, AttrData data) {
        String value = attr.getValue();
        // 取所有接入类产品
        List<KiteProdInst> kiteProdInstList = querySceneInstService.listProdInsts(data.getSceneInstId());
        final KiteProdInst[] prodInsts = new KiteProdInst[1];
        if (KiteListUtils.isNotEmpty(kiteProdInstList)) {
            kiteProdInstList.stream().forEach(prodInst -> {
                List<KiteProdInstFunc> kiteProdInstFuncs = querySceneInstService
                    .listProdInstFuncs(data.getCustId(), prodInst.getProdInstId());
                if (KiteListUtils.isNotEmpty(kiteProdInstFuncs)) {
                    kiteProdInstFuncs.stream().forEach(kiteProdInstFunc -> {
                        if (KiteStringUtils.equalsAny(ProductCache.get(kiteProdInstFunc.getSpecId()).getProdNbr(), LocalKeyConsts.FUNC_PROD_ID_APN, LocalKeyConsts.FUNC_PROD_ID_YF5GAPN)) {
                            prodInsts[0] = prodInst;
                            return;
                        }
                    });
                }
            });
        }
        // 处理APN设置下拉值，从当前实例下获取已经创建好的APN
        List<KiteProdInstFunc> kiteProdInstFuncs = Lists.newArrayList();
        if (!KiteObjectUtils.isEmpty(prodInsts) && !KiteObjectUtils.isEmpty(prodInsts[0])) {
            kiteProdInstFuncs = querySceneInstService
                .listProdInstFuncsByProdId(data.getCustId(), prodInsts[0].getProdInstId(),
                    LocalKeyConsts.FUNC_PROD_ID_APN);
            if (KiteListUtils.isEmpty(kiteProdInstFuncs)) {
                kiteProdInstFuncs = querySceneInstService
                    .listProdInstFuncsByProdId(data.getCustId(), prodInsts[0].getProdInstId(),
                        LocalKeyConsts.FUNC_PROD_ID_NBAPN);
            }
            if (KiteListUtils.isEmpty(kiteProdInstFuncs)) {
                kiteProdInstFuncs = querySceneInstService
                    .listProdInstFuncsByProdId(data.getCustId(), prodInsts[0].getProdInstId(),
                        LocalKeyConsts.FUNC_PROD_ID_5GAPN);
            }
            if (KiteListUtils.isEmpty(kiteProdInstFuncs)) {
                kiteProdInstFuncs = querySceneInstService
                    .listProdInstFuncsByProdId(data.getCustId(), prodInsts[0].getProdInstId(),
                        LocalKeyConsts.FUNC_PROD_ID_YF5GAPN);
            }
            if (!KiteListUtils.isEmpty(kiteProdInstFuncs)) {

                kiteProdInstFuncs = kiteProdInstFuncs.stream().filter(t -> !ActionType.D.equals(t.getActionType()))
                    .collect(Collectors.toList());
                List<KiteAttrValue> attrValues = new ArrayList<>();

                kiteProdInstFuncs.forEach(funcProdInst -> {
                    // 获取APN 新增APN方式，根据不同的APN的方式组装通信计划，资费计划APN设置属性下拉值
                    // 共享、复用的apn展示的是apn域名，定制的展示的是apn的名称
                    KiteAttr wayAttr = funcProdInst.getAttr("200003996");
                    // 使用共享APN 100006950 200003997 共享APN域名
                    // 使用已创建APN 100006951  200003998 复用APN域名
                    // 我要定制 100006952 200004135 APN名称

                    if (Objects.nonNull(wayAttr)) {
                        KiteAttrValue attrValue = new KiteAttrValue();
                        attrValue.setAttrId(attr.getAttrId());
                        attrValue.setAttrNbr(attr.getAttrNbr());
                        if ("100006952".equals(wayAttr.getValue())) {
                            KiteAttr nameAttr = funcProdInst.getAttr("200004135");
                            attrValue.setAttrValue(nameAttr.getValue());
                            attrValue.setAttrValueName(nameAttr.getValueDesc());
                        }
                        else if ("100006950".equals(wayAttr.getValue())) {

                            KiteAttr nameAttr = funcProdInst.getAttr("200003997");
                            attrValue.setAttrValue(nameAttr.getValueDesc());
                            attrValue.setAttrValueName(nameAttr.getValueDesc());

                        }
                        else if ("100006951".equals(wayAttr.getValue())) {

                            KiteAttr nameAttr = funcProdInst.getAttr("200003998");
                            attrValue.setAttrValue(nameAttr.getValue());
                            attrValue.setAttrValueName(nameAttr.getValue());

                        }
                        attrValues.add(attrValue);
                    }

                });
                attr.setAttrValues(attrValues);
                // 只有一个APN的时候要默认勾选
                if (KiteListUtils.isNotEmpty(attrValues) && attrValues.size() == 1) {
                    //准备设置的值
                    String to = attrValues.get(0).getAttrValue();
                    if (!check(attr, inst, data, new String[] {to})) {
                        attr.setValue(to);
                    }
                }
            }
            else {
                attr.setValue("");
                attr.setValueDesc("");
                attr.setAttrValues(new ArrayList<>());
            }
        }
        List<KiteAttrValue> list = attr.getAttrValues();
       if(KiteListUtils.isEmpty(list)){
           // 取所有接入类产品
           if (KiteListUtils.isNotEmpty(kiteProdInstList)) {
               List<KiteAttrValue> attrValues = new ArrayList<>();
               kiteProdInstList.stream().forEach(prodInst -> {
                   KiteAttr apn = prodInst.getAttr("200004104");
                   if (!ObjectUtils.isEmpty(apn)) {
                       KiteAttrValue attrValue = new KiteAttrValue();
                       attrValue.setAttrId(attr.getAttrId());
                       attrValue.setAttrNbr(attr.getAttrNbr());
                       attrValue.setAttrValue(apn.getValue());
                       attrValue.setAttrValueName(apn.getValueDesc());
                       attrValues.add(attrValue);
                   }
               });
               attr.setAttrValues(attrValues);
               // 只有一个APN的时候要默认勾选
               if (KiteListUtils.isNotEmpty(attrValues) && attrValues.size() == 1) {
                   //准备设置的值
                   String to = attrValues.get(0).getAttrValue();
                   if (!check(attr, inst, data, new String[] {to})) {
                       attr.setValue(to);
                   }
               }
           }
        }
       // 加上这个设置这个值的原因，是为了不将实例的actiontype有K设置为M
        data.setTriggerStrategy(TriggerStrategy.LOAD);
        if (KiteStringUtils.isNotEmpty(value) && !value.equals(attr.getValue())) {
            operateInstAttrService.setAttrValue(inst, attr.getFieldName(), attr.getValue(), data.getSceneInstId(), JSON.toJSONString(data));
        }
        operateSceneInstService.setAttr(data.getSceneInstId(), inst.getInstType(), inst.getInstId(), attr);

    }

    /**
     * 校验是否允许设置默认值，已经设置过的就不允许
     * @param attr
     * @param inst
     * @param data
     * @param tos
     * @return true代表存在
     */
    private boolean check(KiteAttr attr, KiteInst inst, AttrData data, String[] tos) {
        if ("sceneTempl".equals(data.getExtAttributes().get("entry"))) {
            return false;
        }
        if ("200004035".equals(attr.getFieldName()) && inst instanceof KiteProdInstFunc) {
            KiteProdInstFunc funcInst = (KiteProdInstFunc) inst;
            List<KiteProdInstFunc> fees = getFeeFunc(data, funcInst);
            //不存在
            if (KiteListUtils.isEmpty(fees)) {
                return false;
            }

            for (KiteProdInstFunc fee : fees) {
                if (fee.getProdInstId().equals(funcInst.getProdInstId())) {
                    continue;
                }
                KiteAttr apnAttr = fee.getAttr(attr.getFieldName());
                if (apnAttr == null || KiteStringUtils.isEmpty(apnAttr.getValue())) {
                    continue;
                }
                String str = apnAttr.getValue();
                List<String> has = Arrays.asList(str.split(","));
                //包含了就
                for (String to :tos){
                    if (has.contains(to)) {
                        return true;
                    }
                }
            }

        }

        return false;
    }

    private List<KiteProdInstFunc> getFeeFunc(AttrData data, KiteProdInstFunc funcInst) {
        //首先获取接入实例，找到下面已经存在的资费
        List<KiteProdInstFunc> kiteProdInstFuncs = querySceneInstService
            .listProdInstFuncs(data.getCustId(), funcInst.getAccProdInstId());
        List<KiteProdInstFunc> fees = KiteListUtils.isEmpty(kiteProdInstFuncs) ?
            null :
            kiteProdInstFuncs.stream().filter(v -> v.getProdId().equals(funcInst.getProdId()))
                .collect(Collectors.toList());
        return fees;
    }
}
